package com.hyf.controller;

import com.hyf.entity.ConfigDataEntity;
import com.hyf.entity.RantQuota;
import com.hyf.entity.TradePitEntity;
import com.hyf.util.AutoConfigUtil;
import jdk.nashorn.internal.ir.LiteralNode;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author hyf
 * @create 2021/10/21 18:41
 */
@Controller
public class AutoConfigController {

    @Autowired
    private AccType accType;
    @Autowired
    private Trade trade;
    @Autowired
    private ExchangeSql exchangeSql;
    @Autowired
    private Matching matching;
    @Autowired
    private Enums enums;

    @Value("${AccType_path}")
    private String accTypePath;
    @Value("${AccType_tem_path}")
    private String accTypeTemPath;
    @Value("${trade_tem_path}")
    private String tradeTemPath;
    @Value("${trade_awsDev_path}")
    private String tradeAwsDevPath;
    @Value("${trade_awsLive_path}")
    private String tradeAwsLivePath;
    @Value("${trade_dev_path}")
    private String tradeDevPath;
    @Value("${trade_qa_path}")
    private String tradeQaPath;
    @Value("${two_path}")
    private String twoPath;
    @Value("${api_awsDev_path}")
    private String apiAwsDevPath;
    @Value("${api_awsLive_path}")
    private String apiAwsLivePath;
    @Value("${api_awsLiveTwo_path}")
    private String apiAwsLiveTwoPath;
    @Value("${api_dev_path}")
    private String apiDevPath;
    @Value("${api_qa_path}")
    private String apiQaPath;
    @Value("${sql_tem_path1}")
    private String sqlTemPath1;
    @Value("${sql_tem_path2}")
    private String sqlTemPath2;
    @Value("${sql_tem_path3}")
    private String sqlTemPath3;
    @Value("${sql_tem2_path}")
    private String sqlTem2Path;
    @Value("${matching_path}")
    private String matchingPath;
    @Value("${coinAddressUrlType1}")
    private String coinAddressUrlType1;
    @Value("${coinSymbol1}")
    private String coinSymbol1;
    @Value("${coinSymbolDepth1}")
    private String coinSymbolDepth1;
    @Value("${config1}")
    private String config1;
    @Value("${symbol1}")
    private String symbol1;
    @Value("${coinAddressUrlType2}")
    private String coinAddressUrlType2;
    @Value("${coinSymbol2}")
    private String coinSymbol2;
    @Value("${coinSymbolDepth2}")
    private String coinSymbolDepth2;
    @Value("${config2}")
    private String config2;
    @Value("${symbol2}")
    private String symbol2;
    @Value("${sql_file_path}")
    private String sqlFilePath;
    @Value("${matching_tem}")
    private String matchingTem;
//    @Value("${trade_k8s_path}")
//    private String tradeK8sPath;
//    @Value("${api_k8s_path}")
//    private String apiK8sPath;

    private Map<String, Object> map = new HashMap<>();

    @RequestMapping("/insetData")
    @ResponseBody
    public String insetData(MultipartFile file) throws Exception {
        List<String> message = checkExcel(file);
        /*if (message.size() != 0) {
            return "数据错误";
        }*/
        Workbook workBook = WorkbookFactory.create(file.getInputStream());
        //获取费率及额度表的数据
        Sheet sheet1 = workBook.getSheetAt(0);
        Sheet sheet2 = workBook.getSheetAt(1);
        int rowNumber1 = sheet1.getPhysicalNumberOfRows()-1;
        int rowNumber2 = sheet2.getPhysicalNumberOfRows()-1;
        List<RantQuota> rantQuotaList = AutoConfigUtil.getRantQuotaList(sheet1, rowNumber1);
        List<TradePitEntity> tradePitList = AutoConfigUtil.getTradePitList(sheet2, rowNumber2);
        //存放去重之后的币种名称列表
        List<String> distinctCoin = new ArrayList<>();
        distinctCoin.addAll(rantQuotaList.stream().map(RantQuota::getTicker).collect(Collectors.toList()));
        distinctCoin.addAll(tradePitList.stream().map(TradePitEntity::getTicker).collect(Collectors.toList()));
        distinctCoin = distinctCoin.stream().distinct().collect(Collectors.toList());
        //将配置信息转化为map，币种名称为key，对象为value
        Map<String, RantQuota> rantQuotaMap = rantQuotaList.stream().collect(Collectors.toMap(RantQuota::getTicker, rantQuota -> rantQuota));
        Map<String, TradePitEntity> tradePitMap = tradePitList.stream().collect(Collectors.toMap(TradePitEntity::getTicker, tradePitEntity -> tradePitEntity));
        //封装整个的配置对象
        List<ConfigDataEntity> configDataEntityList = getConfigDataEntityList(distinctCoin, rantQuotaMap, tradePitMap);
        configDataEntityList.forEach(configDataEntity -> {
            //配置enums文件
            doWriteEnum(configDataEntity);
            //配置AccType文件
            doWriteAccType(configDataEntity);
            //配置trade文件
            doWriteTrade(configDataEntity);
            //配置sql文件
            doWriteSql(configDataEntity);
            //配置match文件
            doWriteMatch(configDataEntity);
        });
        return "配置添加成功";
    }

    public boolean createDir(String dirName) {
        File dir = new File(dirName);
        if (dir.exists()) {
            return false;
        } else {
            return dir.mkdirs();
        }
    }

    public List<String> checkExcel(MultipartFile file) throws Exception {
        List<String> list = new ArrayList<>();
        //错误返回
        List error = new ArrayList();
        //读取工作簿
        Workbook workBook = WorkbookFactory.create(file.getInputStream());
        //读取工作表
        Sheet sheet = workBook.getSheetAt(0);
        int rowNumber = sheet.getPhysicalNumberOfRows();
        //校验是否填写内容
        if (rowNumber <= 0) {
            error.add("文件无内容，请检查");
            return error;
        }
        workBook.close();
        return error;
    }

    //对于AccType添加内容的处理
    public List<String> getAccType(List<String> dataList, List<String> temList, ConfigDataEntity configDataEntity, File fileAccType) {

        List<String> accTypeData = new ArrayList<>();
        accTypeData.add("");
        Integer firSeq = Integer.valueOf(dataList.get(0).substring(dataList.get(0).indexOf("=") + 1, dataList.get(0).indexOf(","))) + 2;
        Integer secSeq = Integer.valueOf(dataList.get(1).substring(dataList.get(1).indexOf("=") + 1, dataList.get(1).indexOf(","))) + 2;
        Integer thirSeq =Integer.valueOf(dataList.get(2).substring(dataList.get(2).indexOf("=") + 1, dataList.get(2).indexOf(","))) + 1;
        Integer forSeq = Integer.valueOf(dataList.get(3).substring(dataList.get(3).indexOf("=") + 1, dataList.get(3).indexOf(","))) + 1;
        Integer fifSeq = Integer.valueOf(dataList.get(4).substring(dataList.get(4).indexOf("=") + 1, dataList.get(4).indexOf(","))) + 1;
        Integer sixSeq = Integer.valueOf(dataList.get(5).substring(dataList.get(5).indexOf("=") + 1, dataList.get(5).indexOf(","))) + 1;
        Integer sevSeq = Integer.valueOf(dataList.get(6).substring(dataList.get(6).indexOf("=") + 1, dataList.get(6).indexOf(","))) + 1;
        Integer eigSeq = Integer.valueOf(dataList.get(7).substring(dataList.get(7).indexOf("=") + 1, dataList.get(7).indexOf(","))) + 1;
        Integer ninSeq = Integer.valueOf(dataList.get(8).substring(dataList.get(8).indexOf("=") + 1, dataList.get(8).indexOf(","))) + 1;
        Integer tenSeq = Integer.valueOf(dataList.get(9).substring(dataList.get(9).indexOf("=") + 1, dataList.get(9).indexOf(","))) + 1;
        map.put("firSeq", firSeq);
        map.put("secSeq", secSeq);
        map.put("thirSeq", thirSeq);
        map.put("forSeq", forSeq);
        map.put("fifSeq", fifSeq);
        map.put("sixSeq", sixSeq);
        map.put("sevSeq", sevSeq);
        map.put("eigSeq", eigSeq);
        map.put("ninSeq", ninSeq);
        map.put("tenSeq", tenSeq);
        if (configDataEntity.getConfigType().equals("0")) {
            //币种和币对都有
            temList.forEach(s -> {
                String s1 = s.replaceAll("TICKER", configDataEntity.getTicker().toUpperCase().contains("$") ?
                        configDataEntity.getTicker().replaceAll("\\$", "RDS_CHAR_DOLLAR").toUpperCase() :
                        configDataEntity.getTicker().toUpperCase())
                        .replaceAll("RDS_CHAR_DOLLAR", "\\$")
                        .replaceAll("ticker", configDataEntity.getTicker().toLowerCase().contains("$") ?
                                configDataEntity.getTicker().replaceAll("\\$", "RDS_CHAR_DOLLAR").toLowerCase() :
                                configDataEntity.getTicker().toLowerCase())
                        .replaceAll("rds_char_dollar", "\\$")
                        .replaceAll("jiaoyiqu", configDataEntity.getJiaoyiqu().toLowerCase())
                        .replaceAll("JIAOYIQU", configDataEntity.getJiaoyiqu().toUpperCase())
                        .replaceAll("firSeq", firSeq.toString())
                        .replaceAll("secSeq", secSeq.toString())
                        .replaceAll("thirSeq", thirSeq.toString())
                        .replaceAll("forSeq", forSeq.toString())
                        .replaceAll("fifSeq", fifSeq.toString())
                        .replaceAll("sixSeq", sixSeq.toString())
                        .replaceAll("sevSeq", sevSeq.toString())
                        .replaceAll("eigSeq", eigSeq.toString())
                        .replaceAll("ninSeq", ninSeq.toString())
                        .replaceAll("tenSeq", tenSeq.toString());
                accTypeData.add(s1);
            });
        } else if (configDataEntity.getConfigType().equals("2")) {
            //只有币种没有币对
            for (int i = 2; i < temList.size(); i++) {
                String s = temList.get(i).replaceAll("TICKER", configDataEntity.getTicker().toUpperCase().contains("$") ?
                        configDataEntity.getTicker().replaceAll("\\$", "RDS_CHAR_DOLLAR").toUpperCase() :
                        configDataEntity.getTicker().toUpperCase())
                        .replaceAll("ticker", configDataEntity.getTicker().toLowerCase().contains("$") ?
                                configDataEntity.getTicker().replaceAll("\\$", "RDS_CHAR_DOLLAR").toLowerCase() :
                                configDataEntity.getTicker().toLowerCase())
                        .replaceAll("RDS_CHAR_DOLLAR", "\\$")
                        .replaceAll("thirSeq", thirSeq.toString())
                        .replaceAll("forSeq", forSeq.toString())
                        .replaceAll("fifSeq", fifSeq.toString())
                        .replaceAll("sixSeq", sixSeq.toString())
                        .replaceAll("sevSeq", sevSeq.toString())
                        .replaceAll("eigSeq", eigSeq.toString())
                        .replaceAll("ninSeq", ninSeq.toString())
                        .replaceAll("tenSeq", tenSeq.toString());
                accTypeData.add(s);
            }
        } else if (configDataEntity.getConfigType().equals("1")) {
            //更新一下map的eigSeq和ninSeq
            List<String> dataList2 = accType.readEigSeqNinSeq(fileAccType, configDataEntity);
            Integer ninSeq2 = Integer.valueOf(dataList2.get(0).substring(dataList2.get(0).indexOf("=") + 1, dataList2.get(0).indexOf(",")));
            Integer eigSeq2 = Integer.valueOf(dataList2.get(1).substring(dataList2.get(1).indexOf("=") + 1, dataList2.get(1).indexOf(",")));
            map.put("eigSeq", eigSeq2);
            map.put("ninSeq", ninSeq2);
            //只有币对没有币种
            for (int i = 0; i < 2; i++) {
                String s = temList.get(i).replaceAll("TICKER", configDataEntity.getTicker().toUpperCase().contains("$") ?
                        configDataEntity.getTicker().replaceAll("\\$", "RDS_CHAR_DOLLAR").toUpperCase() :
                        configDataEntity.getTicker().toUpperCase())
                        .replaceAll("RDS_CHAR_DOLLAR", "\\$")
                        .replaceAll("ticker", configDataEntity.getTicker().toLowerCase().contains("$") ?
                                configDataEntity.getTicker().replaceAll("\\$", "RDS_CHAR_DOLLAR").toLowerCase() :
                                configDataEntity.getTicker().toLowerCase())
                        .replaceAll("rds_char_dollar", "\\$")
                        .replaceAll("jiaoyiqu", configDataEntity.getJiaoyiqu().toLowerCase())
                        .replaceAll("JIAOYIQU", configDataEntity.getJiaoyiqu().toUpperCase())
                        .replaceAll("firSeq", firSeq.toString())
                        .replaceAll("secSeq", secSeq.toString());
                accTypeData.add(s);
            }
        } else {
            return null;
        }
        return accTypeData;
    }

    //封装整个的配置对象
    public List<ConfigDataEntity> getConfigDataEntityList(List<String> distinctCoin,
                                                          Map<String, RantQuota> rantQuotaMap,
                                                          Map<String, TradePitEntity> tradePitMap) {
        List<ConfigDataEntity> configDataEntityList = new ArrayList<>();
        distinctCoin.forEach(ticker -> {
            //币种币对都有
            if (rantQuotaMap.get(ticker) != null && tradePitMap.get(ticker) != null) {
                ConfigDataEntity configData = new ConfigDataEntity();
                BeanUtils.copyProperties(rantQuotaMap.get(ticker), configData);
                BeanUtils.copyProperties(tradePitMap.get(ticker), configData);
                configData.setConfigType("0");
                configDataEntityList.add(configData);
            } else if (rantQuotaMap.get(ticker) == null && tradePitMap.get(ticker) != null) {
                ConfigDataEntity configData = new ConfigDataEntity();
                BeanUtils.copyProperties(tradePitMap.get(ticker), configData);
                configData.setConfigType("1");
                configDataEntityList.add(configData);
            } else {
                ConfigDataEntity configData = new ConfigDataEntity();
                BeanUtils.copyProperties(rantQuotaMap.get(ticker), configData);
                configData.setConfigType("2");
                configDataEntityList.add(configData);
            }
        });
        return configDataEntityList;
    }

    //执行枚举中的配置
    public void doWriteEnum(ConfigDataEntity configDataEntity) {
            System.out.println(configDataEntity.toString());
            //枚举类中的配置
            if (configDataEntity.getConfigType().equals("0")) {
                File temAddressUrl = new File(coinAddressUrlType1);
                File temCoinSymbol = new File(coinSymbol1);
                File temDepth = new File(coinSymbolDepth1);
                File temConfig = new File(config1);
                File temSymbol = new File(symbol1);
                List<String> temDepthenums = enums.readLastNLine(temDepth);
                List<String> temSymbolenums = enums.readLastNLine(temSymbol);
                List<String> temDepthData = enums.getSymbolDepth(temDepthenums, configDataEntity);
                List<String> temSymbolData = enums.getSymbol(temSymbolenums, configDataEntity);
                enums.writeData(coinSymbolDepth2, temDepthData);
                enums.writeData(symbol2, temSymbolData);
                List<String> temCoinAddressenums = enums.readLastNLine(temAddressUrl);
                List<String> coinAddressData = enums.getCoinAddress(temCoinAddressenums, configDataEntity);
                enums.writeData(coinAddressUrlType2, coinAddressData);
                List<String> temCoinSymbolenums = enums.readLastNLine(temCoinSymbol);
                List<String> temConfigenums = enums.readLastNLine(temConfig);
                List<String> temCoinSymbolData = enums.getCoinSymbol(temCoinSymbolenums, configDataEntity);
                List<String> temConfigData = enums.getConfig(temConfigenums, configDataEntity);
                enums.writeData(coinSymbol2, temCoinSymbolData);
                enums.writeData(config2, temConfigData);
            }
            if (configDataEntity.getConfigType().equals("2")) {
                File temAddressUrl = new File(coinAddressUrlType1);
                List<String> temCoinAddressenums = enums.readLastNLine(temAddressUrl);
                List<String> CoinAddressData = enums.getCoinAddress(temCoinAddressenums, configDataEntity);
                enums.writeData(coinAddressUrlType2, CoinAddressData);
                File temCoinSymbol = new File(coinSymbol1);
                File temConfig = new File(config1);
                List<String> temCoinSymbolenums = enums.readLastNLine(temCoinSymbol);
                List<String> temConfigenums = enums.readLastNLine(temConfig);
                List<String> temCoinSymbolData = enums.getCoinSymbol(temCoinSymbolenums, configDataEntity);
                List<String> temConfigData = enums.getConfig(temConfigenums, configDataEntity);
                enums.writeData(coinSymbol2, temCoinSymbolData);
                enums.writeData(config2, temConfigData);
            }
            if (configDataEntity.getConfigType().equals("1")) {
                File temDepth = new File(coinSymbolDepth1);
                File temSymbol = new File(symbol1);
                List<String> temDepthenums = enums.readLastNLine(temDepth);
                List<String> temSymbolenums = enums.readLastNLine(temSymbol);
                List<String> temDepthData = enums.getSymbolDepth(temDepthenums, configDataEntity);
                List<String> temSymbolData = enums.getSymbol(temSymbolenums, configDataEntity);
                enums.writeData(coinSymbolDepth2, temDepthData);
                enums.writeData(symbol2, temSymbolData);
            }
    }

    //执行AccType文件的配置
    public void doWriteAccType(ConfigDataEntity configDataEntity) {
            //读取AccType.properties文件最后添加的内容
            File fileAccType = new File(accTypePath);
            //读取模板文件
            File temAccType = new File(accTypeTemPath);
            List<String> dataList = accType.readLastNLine(fileAccType);
            List<String> temList = accType.readLastNLine(temAccType);
            //获取这次需要添加的AccType配置内容
            List<String> acctypeData = getAccType(dataList, temList, configDataEntity, fileAccType);
            if (acctypeData != null) {
                accType.writeData(accTypePath, acctypeData);
            }
    }

    //执行trade文件的配置
    public void doWriteTrade(ConfigDataEntity configDataEntity) {
            //获取exchange_trade文件的模板
            List<String> temTrade = trade.readLastNLine(new File(tradeTemPath), configDataEntity);
            //这次的trade文件数据
            List<String> tradeData = trade.getTrade(temTrade, configDataEntity);
            //往exchange中写入数据
            trade.writeData(tradeAwsLivePath, tradeData);
            trade.writeData(tradeDevPath,tradeData);
            trade.writeData(tradeQaPath,tradeData);
            //往 2.0中插入数据
            trade.writeData(twoPath, tradeData);
            //往trade-api中插入数据
            trade.writeData(apiQaPath, tradeData);
            trade.writeData(apiAwsLivePath, tradeData);
            trade.writeData(apiDevPath,tradeData);
    }

    //执行sql文件的配置
    public void doWriteSql(ConfigDataEntity configDataEntity) {
            //在exchange-sql中创建目录和文件
            SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd");
            String date = sf.format(new Date());
            String dirName1 = sqlFilePath + date.substring(0, 6);
            String dirName2 = sqlFilePath + date.substring(0, 6) + "\\" + date;
            String dirName3 = sqlFilePath + date.substring(0, 6) + "\\" + date + "\\" + configDataEntity.getTicker().toLowerCase();
            String dirName4 = sqlFilePath + date.substring(0, 6) + "\\" + date + "\\" + configDataEntity.getTicker().toLowerCase() + "\\" + "day2";
            createDir(dirName1);
            createDir(dirName2);
            createDir(dirName3);
            //创建文件
            String fileName1 = dirName3 + "\\" + "01NewCoin02-add-exchange.FeeAccount.sql";
            String fileName2 = "";
            if (!configDataEntity.getConfigType().equals("2")) {
                createDir(dirName4);
                fileName2 = dirName4 + "\\" + "02OpenTrade-add-exchange.fee.sql";

                //第二个文件
                List<String> temSql2 = exchangeSql.readLastNLine(new File(sqlTem2Path));
                List<String> sqlData2 = exchangeSql.getExchangeSql2(temSql2, configDataEntity);
                exchangeSql.writeData(fileName2, sqlData2);
            }
            //往文件中写入数据
            //第一个文件
            List<String> temSql1;
            if (configDataEntity.getConfigType().equals("0")) {
                temSql1 = exchangeSql.readLastNLine(new File(sqlTemPath1));
            } else if (configDataEntity.getConfigType().equals("2")) {
                temSql1 = exchangeSql.readLastNLine(new File(sqlTemPath2));
            } else {
                temSql1 = exchangeSql.readLastNLine(new File(sqlTemPath3));
            }
            List<String> sqlData1 = exchangeSql.getExchangeSql1(temSql1, configDataEntity, map);

            exchangeSql.writeData(fileName1, sqlData1);
    }

    //执行match文件的配置
    public void doWriteMatch(ConfigDataEntity configDataEntity) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd");
        String date = sf.format(new Date());
            //本次的matching模板
            if (!configDataEntity.getConfigType().equals("2")) {
                List<String> temMatch = matching.readLastNLine(new File(matchingTem));
                List<String> matchData = matching.getMatching(temMatch, configDataEntity, map);
                String matchDir1 = matchingPath + date.substring(0, 6);
                String matchDir2 = matchingPath + date.substring(0, 6) + "\\" + date;
                createDir(matchDir1);
                createDir(matchDir2);
                String name = configDataEntity.getTicker().toLowerCase() + configDataEntity.getJiaoyiqu().toLowerCase();
                matching.writeData(matchDir2 + "\\" + name + ".conf.properties", matchData);
            }
    }
}
